<script setup>
import { ref, watch, onMounted, nextTick } from "vue";
import MarkdownIt from "vue3-markdown-it";

/* pc端聊天组件
 * props.chat数据格式：
 *   对象数组，对象有以下属性：
 *     id
 *     avatar 头像
 *     content 内容
 *     originalType 0-自己 1-对方
 *     replyId 可选，回复的消息的id
 *     name 用户名
 *
 * 使用前先安装vue3-markdown-it，scss*/

const props = defineProps({
  chat: { type: Array, default: () => [] },
  title: { type: String, default: "聊天" },
  showName: { type: Boolean, default: true },
});
const emits = defineEmits(["send", "scroll"]);

const text = ref("");

const currentResponse = ref(null);

const chatRef = ref();

//引用并回复
function setResponse(item) {
  currentResponse.value = item;
}

//取消引用
function cancel() {
  currentResponse.value = null;
}

//发送
function send() {
  emits("send", text.value, currentResponse.value);
  text.value = "";
}

function replyContent(replyId) {
  return props.chat.find((e) => e.id === replyId).content;
}

//滚动事件
let lastScrollHeight = 0;
const handleScroll = () => {
  lastScrollHeight = chatRef.value.scrollHeight;
  if (chatRef.value.scrollTop === 0) {
    emits("scroll");
    nextTick(() => {
      chatRef.value.scrollTop = chatRef.value.scrollHeight - lastScrollHeight;
      lastScrollHeight = chatRef.value.scrollHeight;
    });
  }
};
onMounted(() => {
  chatRef.value.addEventListener("scroll", handleScroll);
});

watch(
  () => props.chat.length,
  (val) => {
    if (val) {
      setTimeout(() => {
        chatRef.value.scrollTop = chatRef.value.scrollHeight;
      });
    }
  }
);
</script>

<template>
  <div class="chat-container">
    <div class="header">
      <slot name="headerPrefix"></slot>
      <div class="header-title">{{ props.title }}</div>
      <slot name="headerSuffix"></slot>
    </div>

    <div class="outer">
      <div class="outer-1">
        <div class="outer-2">
          <div class="chat" ref="chatRef">
            <div
              v-for="(item, index) in props.chat"
              :key="index"
              :class="item.originType === 0 ? 'chat-item_mine' : 'chat-item'"
            >
              <img :src="item.avatar" class="avatar" alt="" />
              <div>
                <div class="chat-item-name">{{ item.name }}</div>
                <div class="chat-item-text" @click="setResponse(item)">
                  <div v-if="item.replyId" class="chat-item-text_reply">
                    {{ replyContent(item.replyId) }}
                  </div>
                  <MarkdownIt :source="item.content"></MarkdownIt>
                </div>
              </div>
              <div class="avatar"></div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div class="send">
      <div v-if="currentResponse" class="send-reply">
        <div class="send-reply-box">
          <div>回复</div>
          <div class="send-cancel" @click="cancel"></div>
        </div>
        <div class="send-reply-text">{{ currentResponse.content }}</div>
      </div>

      <div class="send-box">
        <textarea
          placeholder="单击某条消息可以选择要引用回复的消息"
          v-model="text"
          rows="3"
        />
        <button @click="send" class="send-button">发送</button>
      </div>
    </div>
  </div>
</template>

<style lang="scss">
$main-color: #3554d1;
$sub-color: rgba(0, 0, 0, 0.05);
$sub-text: rgba(0, 0, 0, 0.5);

:deep(.hljs) {
  background-color: $sub-color;
  color: black;
}

.chat-container{  
  display: flex;
  flex-direction: column;
  height:100%;
}

.header {
  height:70px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
  padding: 0 16px;
}

.chat {
  overflow-y: scroll;
  display: flex;
  flex-direction: column;
  gap: 16px;
  height:100%;
}

.chat-item {
  display: flex;
  gap: 8px;
  margin: 0 8px;

  p {
    margin: 0;
  }

  &-text {
    background: white;
    padding: 8px;
    border-radius: 8px;
    display: inline-block;

    &_reply {
      background: $sub-color;
      padding: 8px;
      border-radius: 4px;
      margin-bottom: 8px;
      color: gray;
      font-size: 14px;
    }
  }

  &-name {
    color: $sub-text;
  }

  &_mine {
    @extend .chat-item;
    flex-direction: row-reverse;

    .chat-item-text {
      background: $main-color;
      color: white;
    }

    .chat-item-name {
      text-align: right;
    }

    .chat-item-text_reply {
      color: white;
    }
  }
}

.avatar {
  width: 36px;
  height: 36px;
  border-radius: 50%;
  flex-shrink: 0;
}

.send {
  flex-shrink: 0;
  margin-top: 16px;
  padding: 0 8px;

  &-reply {
    padding: 8px;
    border-radius: 8px;
    color: $sub-text;
    background: $sub-color;
    margin-bottom: 8px;
    font-size: 12px;

    &-text {
      overflow: hidden;
      text-overflow: ellipsis;
      display: -webkit-box;
      -webkit-line-clamp: 2;
      -webkit-box-orient: vertical;
    }

    &-box {
      display: flex;
      justify-content: space-between;
      margin-bottom: 4px;
    }
  }

  &-cancel {
    width: 16px;
    height: 16px;
    border: 1px solid $sub-text;
    border-radius: 50%;
    color: $sub-text;
    cursor: pointer;
    text-align: center;
    line-height: 16px;

    &:before {
      content: "x";
    }
  }

  &-box {
    display: flex;
    gap: 12px;
    width: 100%;

    textarea {
      flex-grow: 1;
      border: 1px solid $main-color;
      border-radius: 4px;
      font-size: 16px;
    }
  }

  &-button {
    background: $main-color;
    border-radius: 4px;
    height: 32px;
    color: white;
    padding: 8px 15px;
    display: flex;
    align-items: center;
    cursor: pointer;
    border: none;
  }
}

.outer {
  position: relative;
  height: 100%;
  width: 100%;

  &-1 {
    display: flex;
    flex-direction: column;
    height: 100%;
  }

  &-2 {
    flex-grow: 1;
    height: 0;
  }
}
</style>
